package com.yy.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.util.IdUtil;

import com.yy.common.constant.HttpStatus;
import com.yy.common.constant.PmsConstants;
import com.yy.common.exception.ServiceException;
import com.yy.common.utils.SecurityUtils;
import com.yy.common.utils.StringUtils;
import com.yy.config.PayService;
import com.yy.domain.*;
import com.yy.dto.PayTradeOrderDTO;
import com.yy.mapper.*;
import com.yy.service.IPayTradeOrderService;
import com.yy.system.service.ISysConfigService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 支付订单Service业务层处理
 * 
 * @author leige
 * @date 2023-10-31
 */
@Service
@Log4j2
public class PayTradeOrderServiceImpl implements IPayTradeOrderService
{
    @Resource
    private PayTradeOrderMapper payTradeOrderMapper;

    @Resource
    private AssetHouseMapper assetHouseMapper;

    @Resource
    private PayPrestoreAccountMapper payPrestoreAccountMapper;

    @Resource
    private PayPrestoreMapper payPrestoreMapper;

    @Resource
    private ISysConfigService configService;

    @Resource
    private PayTradeOrderItemMapper payTradeOrderItemMapper;

    @Resource
    private PayOrderMapper payOrderMapper;

@Autowired
private PayService payService;
    /**
     * 创建支付的订单包含订单的详情
     * 操作的表
     *   pay_trade_order  订单主表
     *   pay_trade_order_item 订单详情表
     *   pay_order   生成的订单候选项目表
     *   pay_prestore  预存明细表
     *   pay_prestore_account  预存账户表
     * @param payTradeOrderDTO
     * @return
     */
    @Override
    @Transactional
    public int addPayTradeOrder(PayTradeOrderDTO payTradeOrderDTO) {
        String payType = payTradeOrderDTO.getPayType();//支付类型
        Long houseId = payTradeOrderDTO.getHouseId();//商铺ID
        Long ownerId = payTradeOrderDTO.getOwnerId();//业主ID
        String ownerName = payTradeOrderDTO.getOwnerName();//业主姓名
        String yesNo = payTradeOrderDTO.getYesNo();//是否代扣
        BigDecimal receivableAmount = payTradeOrderDTO.getReceivableAmount();//实付金额
        BigDecimal withholdAmount = payTradeOrderDTO.getWithholdAmount();//代扣金额
        List<PayOrder> payOrders = payTradeOrderDTO.getPayOrders();//订单详情

        //根据商铺ID查询商铺信息
        AssetHouse assetHouse = assetHouseMapper.selectAssetHouseById(houseId);
        if(ObjectUtils.isEmpty(assetHouse)){
            throw  new ServiceException("商铺不存在");
        }
        //计算总金额
        BigDecimal totalAmount=new BigDecimal("0");
        String subject="商铺["+assetHouse.getName()+"]的";//商铺[JRG-B26-1-101]的[空调使用费][公共区域水费]缴费订单
        String body="";//|空调使用费||公共区域水费|
        for (PayOrder payOrder : payOrders) {
            subject+="["+payOrder.getItemName()+"]";
            body+="|"+payOrder.getItemName()+"|";
            totalAmount=totalAmount.add(payOrder.getAmt());
        }
        subject+="缴费订单";
        //处理代扣
        if(yesNo.equals(PmsConstants.PAY_WITHHOLD_Y)){
            //处理代扣的问题
            //根据业主ID查询业主的账户信息
            PayPrestoreAccount account = this.payPrestoreAccountMapper.queryPayPrestoreAccountByOwnerId(ownerId);
            if(null==account){
                throw new ServiceException("当前业主没有预存账户");
            }
            if(account.getAmt().doubleValue()<withholdAmount.doubleValue()){
                throw new ServiceException("当前业主预存账户余额不足");
            }
            //账户余额足  减余额，加流水
            account.setAmt(account.getAmt().subtract(withholdAmount));
            //更新
            this.payPrestoreAccountMapper.updatePayPrestoreAccount(account);
            //记录流水pay_prestore
            PayPrestore prestore=new PayPrestore();
            String prefix = configService.selectConfigByKey(PmsConstants.PREFIX_PRESTORE_YC);
            if(StringUtils.isBlank(prefix)){
                throw new ServiceException("预存的单号前缀没有配置");
            }
            prestore.setOrderNo(prefix + IdUtil.getSnowflake().nextIdStr());
            prestore.setType(PmsConstants.PAY_PRESTORE_TYPE_WITHHOLD);
            prestore.setCreateTime(new Date());
            prestore.setCreateBy(SecurityUtils.getUsername());
            prestore.setState(PmsConstants.PAY_ORDER_STATE_2);
            prestore.setPayType(PmsConstants.PAY_TYPE_CASH);
            prestore.setFeeUserId(ownerId);
            prestore.setFeeUserName(ownerName);
            prestore.setAmt(withholdAmount);
            this.payPrestoreMapper.insertPayPrestore(prestore);
        }

        PayTradeOrder tradeOrder=new PayTradeOrder();
        String key = configService.selectConfigByKey(PmsConstants.PREFIX_ORDER_TRADE);
        if(StringUtils.isBlank(key)){
            throw new ServiceException("订单编号的前缀没有配置");
        }
        String id=key+ IdUtil.getSnowflake().nextIdStr();
        tradeOrder.setId(id);
        tradeOrder.setOwnerId(ownerId);
        tradeOrder.setOwnerName(ownerName);
        tradeOrder.setBody(body);
        tradeOrder.setSubject(subject);
        tradeOrder.setPayType(payType);
        tradeOrder.setTotalAmount(totalAmount);
        tradeOrder.setReceivableAmount(receivableAmount);
        tradeOrder.setYesNo(yesNo);
        tradeOrder.setWithholdAmount(withholdAmount);
        tradeOrder.setState(PmsConstants.PAY_ORDER_STATE_0);
        if(payType.equals(PmsConstants.PAY_TYPE_CASH)){//现金
            //直接支付成功
            tradeOrder.setState(PmsConstants.PAY_ORDER_STATE_2);
            tradeOrder.setSuccessTime(new Date());
        }
        tradeOrder.setCreateBy(SecurityUtils.getUsername());
        tradeOrder.setCreateTime(new Date());

        //添加订单明细
        for (PayOrder payOrder : payOrders) {
            PayTradeOrderItem item=new PayTradeOrderItem();
            item.setOrderId(payOrder.getOrderId());
            item.setItemName(payOrder.getItemName());
            item.setTradeId(id);
            item.setNum(payOrder.getNum());
            item.setPrice(payOrder.getPrice());
            item.setAmt(payOrder.getAmt());
            this.payTradeOrderItemMapper.insertPayTradeOrderItem(item);
            //更新pay_order
            payOrder.setPayState(PmsConstants.PAY_ORDER_STATE_2);
            payOrder.setPayTime(new Date());
            payOrder.setPayType(payType);
            this.payOrderMapper.updatePayOrder(payOrder);
        }
        return this.payTradeOrderMapper.insertPayTradeOrder(tradeOrder);
    }

    /**
     * 查询支付订单列表
     *
     * @param payTradeOrder
     * @return
     */
    @Override
    public List<PayTradeOrder> selectPayTradeOrderList(PayTradeOrder payTradeOrder) {
        return this.payTradeOrderMapper.selectPayTradeOrderList(payTradeOrder);
    }

    /**
     * 根据主订单ID查询订单详情
     *
     * @param id
     * @return
     */
    @Override
    public List<PayTradeOrderItem> queryTradeOrderItemByTradeId(String id) {
        return this.payTradeOrderItemMapper.queryTradeOrderItemByTradeId(id);
    }

    @Override
    public PayTradeOrder selectPayTradeOrderById(String outTradeNo) {
        return this.payTradeOrderMapper.selectPayTradeOrderById(outTradeNo);
    }

    /**
     * 支付成功
     *
     * @param outTradeNo
     * @param tradeNo
     */
    @Override
    @Transactional
    public void paySuccess(String outTradeNo, String tradeNo) {
        //更新订单状态和支付时间，和支付宝的订单号
        PayTradeOrder payTradeOrder = this.payTradeOrderMapper.selectPayTradeOrderById(outTradeNo);
        if (ObjectUtils.isEmpty(payTradeOrder)) {
            throw new ServiceException("订单号不存在");
        }
        if (payTradeOrder.getState().equals(PmsConstants.PAY_ORDER_STATE_0)) {
            //判断是不是真的支付成功
            Map<String, Object> map = payService.queryPay(outTradeNo);
            if (!map.get("code").equals(HttpStatus.SUCCESS)) {
                log.error("检查到订单没有支付，是恶意回调，记录IP");
                throw new ServiceException("检查到订单没有支付，是恶意回调");
            }
            String tradeStatus = map.get("tradeStatus").toString();
            if (!tradeStatus.equals("TRADE_SUCCESS")) {
                log.error("检查到订单没有支付");
                throw new ServiceException("检查到订单没有支付");
            }
            payTradeOrder.setState(PmsConstants.PAY_ORDER_STATE_2);//支付成功
            payTradeOrder.setSuccessTime(new Date());
            payTradeOrder.setTradeNo(tradeNo);
            //更新
            this.payTradeOrderMapper.updatePayTradeOrder(payTradeOrder);
            //更新pay_order表里面的状态
            //根据订单号查询详情ID
            List<PayTradeOrderItem> orderItems = this.payTradeOrderItemMapper.queryTradeOrderItemByTradeId(tradeNo);
            List<String> orderIds = orderItems.stream().map(item -> item.getOrderId()).collect(Collectors.toList());
            this.payOrderMapper.updatePayOrderByOrderIds(orderIds,payTradeOrder.getPayType());
            return;
        }
        throw new ServiceException("订单状态不是订单创建状态");
    }

}
